using System;
using System.Collections.Generic;
using System.ComponentModel;

using CureConsulting;
using CureConsulting.Business;

using Bug.Net.Common.DataObjects;

namespace Bug.Net.Business.BusinessObjects
{
	/// <summary>
	/// Business Object for role.
	/// </summary>
	public partial class RoleBO : BusinessObjectBase
	{
		#region Constructors

		/// <summary>
		/// Create a RoleBO object
		/// </summary>
		public RoleBO()
		{
			this.role = new Role();
		}

		/// <summary>
		/// Create a RoleBO object
		/// </summary>
		public RoleBO(int id) : this()
		{
			this.role.Id = id;
		}
		
		/// <summary>
		/// Create a RoleBO object
		/// </summary>
		/// <param name="name"></param>
		/// <param name="description"></param>
		public RoleBO( string name, string description ) : this()
		{
			this.role.Name = name;
			this.role.Description = description;
		}

		/// <summary>
		/// Create a RoleBO object
		/// </summary>
		/// <param name="Role"></param>
		public RoleBO(Role role)
		{
			if(role != null)
			{
				this.role = role;
			}
			else
			{
				throw new ArgumentNullException();
			}
		}
		
		#endregion
		
		#region Member Variables
		
		private Role role;
		
		protected SortableBindingList<LoginBO> _logins;
		
		#endregion
		
		#region Private Methods
		
		void _logins_ListChanged(object sender, ListChangedEventArgs e)
        {
            switch (e.ListChangedType)
            {
                case ListChangedType.ItemAdded:
                    if (_logins[e.NewIndex] != null)
                    {
                        POCO.Logins.Insert(e.NewIndex, _logins[e.NewIndex].POCO);
                    }
                    break;

                case ListChangedType.ItemDeleted:
					POCO.Logins.RemoveAt(e.NewIndex);
                    break;
					
				case ListChangedType.Reset:
                    POCO.Logins.Clear();
                    break;

                default:
                    break;
			}
        }
		
		
		#endregion
		
		#region Public Properties
		
		/// <summary>
        /// Property for POCO
        /// </summary>
        public Role POCO
        {
            get { return role; }
        }
		
		/// <summary>
        /// Property for Id
        /// </summary>
        public override int? Id
        {
            get { return role.Id; }
			set
			{
				if(value.HasValue)
					role.Id = value;
			}
        }
		
		/// <summary>
		/// Role Name
		/// </summary>
		public virtual string Name
		{
			get { return role.Name; }
			set
			{
				role.Name = value;
				NotifyPropertyChanged("Name");
			}
		}

		/// <summary>
		/// Role Description
		/// </summary>
		public virtual string Description
		{
			get { return role.Description; }
			set
			{				
				role.Description = (value != null && value.Length > 0) ? value : null;
				NotifyPropertyChanged("Description");
			}
		}

		/// <summary>
		/// Role Logins
		/// </summary>
		[ManyToMany]
		public virtual SortableBindingList<LoginBO> Logins
		{
			get
			{
				if(_logins == null)
				{			
					SortableBindingList<LoginBO> retVal = new SortableBindingList<LoginBO>();

					if (role.Logins != null)
					{
						foreach (Login tempLogin in role.Logins)
						{
							retVal.Add(new LoginBO(tempLogin));
						}
					}
		
					_logins = retVal;
					_logins.ListChanged += new ListChangedEventHandler(_logins_ListChanged);
				}
				
				return _logins;
			}
		}

		
		/// <summary>
        /// Property for Dirty
        /// </summary>
        public override bool Dirty
        {
            get { return role.Dirty; }
        }
		
		/// <summary>
        /// Property for IsNew
        /// </summary>
        public override bool IsNew
        {
            get { return role.IsNew; }
        }
		
		#endregion
		
		#region Public Methods
		
		/// <summary>
		/// Update a RoleBO object
		/// </summary>
		public void UpdateBO(Role role)
		{
			this.role.Id = role.Id;
			this.role.Name = role.Name;
			this.role.Description = role.Description;
		}
		
		/// <summary>
		/// Override Equals to compare object properties.
		/// Note that child collections are ignored to avoid performance issues
		/// and possible circular references. Any DateTime properties will be considered equal
		/// if they differ by less than a second.  This is necessary because the RDBMS datetime data type
		/// (on Oracle or Sql Server) has less precision than the .Net DateTime struct.
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public override bool Equals(object obj)
		{
			if(obj == null || obj.GetType() != this.GetType()) { return false; }
			
			if(Object.ReferenceEquals(this, obj)) { return true; }
			
			RoleBO other = (RoleBO)obj;

			return
			(
				this.Id == other.Id
				&& this.Name == other.Name
				&& this.Description == other.Description
			);
			
		}
		
		/// <summary>
		/// This class is mutable and therefore should not be used as a Hashtable key.
		/// GetHashCode will return the same value for all instances of this class.
		/// </summary>
		/// <returns></returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		/// <summary>
		/// Reset the dirty flag
		/// </summary>
		public override void ResetDirty()
		{
			role.ResetDirty();
		}
		
		#endregion
	}
}